Azure DevOps を使って、AWSへのCI/CD環境を簡単に構築する方法
いわさです。
Azure DevOps (旧:Visual Studio Team Services) ではGUIベースで簡単にCI/CDパイプラインを構築することが出来ます。
名前にAzureの文字が含まれていますが、AWSへの統合も簡単に行うことが出来ます。
今回はAWSより提供されている、"AWS Toolkit for Azure DevOps"という Azure DevOps拡張を用いることでAWS環境へのCI/CDパイプラインを構築しました。
本記事では以下を行います。
- Visual Studio for Mac を用いて、シンプルな ASP.NET Core プロジェクトを作成
- Azure DevOps上のリポジトリへソースコードをプッシュし、パイプラインを構築
- デプロイタスクとしてToolkitサイト内でも取り上げられている、"Amazon S3へのデプロイ"、"ElasticBeanstalkへのデプロイ"の2つを作成
※ Azure DevOpsアカウントと、AWSアカウントが必要になります
※ ユニットテストの実施は行いません
Webアプリケーションの作成
Visual Studio for Macを使用して、テンプレートを使ったシンプルなWebアプリケーションを作成します。
本記事ではCI/CD構築を目的としているため、初期状態のまま使用しソリューションの構成などについては解説しません。
Visual Studio for Macを起動し、新しいプロジェクトの "Webとコンソール" -> "アプリ" -> "Webアプリケーション(Model-View-Controller)" を選択します。
対象のフレームワークは .NET Core 3.1を選択し、認証なしを選択します。
プロジェクト名、ソリューション名は任意です。
"バージョンコントロールにGitを使用する"を選択してください。
起動されたら、実行ボタンを押してみます。
Webアプリケーションが起動しました!
今回はこのWebアプリケーションを使って自動化のパイプラインを構築します。
リモートリポジトリの作成と更新
Azure DevOpsはソースコードリポジトリ、パイプライン、課題・タスクなどが統合された環境です。
ここではgitリポジトリをAzureDevOps上に作成し、先程作成したWebアプリケーションをプッシュします。
Azure DevOpsではプロジェクトを作成し、その中でリポジトリやパイプラインを管理します。
まずはCreate new projectからプロジェクトを作成します。
バージョン管理にGitを選択してください。
作成できたら、ReposメニューからFilesを選択します。
HTTPSのURLをコピーします。
Visual Studioに戻って、バージョンコントロールメニューから"確認してコミット"を選択してコミットを行います。
コミットが終わったら、"ブランチとリモートを管理する"からリモートリポジトリのURLを入力し、プッシュを行います。
認証情報が必要になると思います。
ここではHTTPSアクセス用の認証情報を作成し使用します。
"Create Credential"を選択し、生成されたUsernameとPasswordを先程のダイアログに入力してください。
入力が完了したらプッシュ処理を継続します。
プッシュが完了したか確認してみます。
Repos -> Files を参照するとソースコードが確認できていればOKです。
Amazon S3へデプロイするパイプラインを作成
いよいよここからデプロイパイプラインを作成します。
PipelinesメニューからPipelinesを選択し、Create Pipelineを選んでください。
リポジトリを選択する画面が表示されると思いますが、ここでは選択せずに下部の"Use the classic editor"を選択してください。
最新の機能ではYAMLを使ってパイプラインを記述しますが、本日はGUIでポチポチタスクを選んでいく旧来の方法を取りたいと思います。
ソースはAzure Repos Gitを選択します。
テンプレートで、"ASP.NET Core"を選択してください。
テンプレートを選択することで、必要な前処理やビルドコマンドなどが自動で設定されます。(便利)
テンプレートが設定されたらジョブの右側の"+"ボタンを押します。
タスク追加画面が表示されるので、"AWS Toolkit for Azure DevOps"を選択してください。
初回はAzure DevOpsアカウントへの拡張機能のインストールから行う必要があります。
Visual Studio Marketplaceに遷移するので "Get it free"を選択します。
対象のAzureDevOpsアカウントへインストールを行ってください。
もしオンプレミス版のAzure DevOps Sever(旧:Visual Studio Team Foundation Server)を使っている場合は、拡張機能をダウンロードしインストールすることが出来ます。
インストールが完了したら、パイプラインタスクに"Amazon S3 Upload"を追加してください。
追加後、Pulishの次に配置します。
AWS側でデプロイ作業用にIAMユーザーを作成しました。
アクセスキーとシークレットを入力します。
スイッチロール周りも少し試してたのですが、うまくいかなかったので今回は断念しました。
進展があったら別で記事にしたいと思います。
デプロイ先S3の情報を入力します。
バケットが存在しない場合に作成するオプションもあります。
Source Folderは"$(Build.ArtifactStagingDirectory)"、Filename Patternsは "*.zip"を入力してください。
Runボタンか、Save&Queueボタンで実行してみてください。
オールグリーンになったらS3バケットを確認してみましょう。
出力されていました!
Elastic Beanstalkに展開
出力されたファイルがWebアプリケーションとして展開可能なものか、念の為確認してみます。
S3バケットに出力されたzipファイルのオブジェクトURLをコピーします。
Elastic Beanstalkで新規アプリケーションを作成してください。
プラットフォームは .NET Coreを選択し、ソースコード元に先程のS3オブジェクトURLを入力します。
デプロイ完了したらURLを開いてみましょう。
いいですね!
これで、タスク実行時の自動ビルド、S3への自動展開パイプラインが作成出来ました。
Elastic Beanstalk へのデプロイ自動化
今のままだと毎回S3からElastic Beanstalkへの手動展開が必要になるので、直接Elastic Beanstalkへ自動デプロイするよう変更します。
また、現時点ではまだトリガーの設定をしていないため、gitプッシュされたタイミングでパイプラインが自動実行される状態になっていません。
そのあたりの設定もしていきます。
先程と同じ要領でパイプラインのタスクに"AWS Elastic Beanstalk Deploy Application"を追加します。
AWS Toolkitをインストールしたことで上記タスクが追加できるようになっていると思います。
S3アップロードのタスクは無効化しておきます。
※ Elastic Beanstalkへのデプロイとあわせて実行することも可能です!
Deploy to Elastic Beanstalk の設定に必要な情報を調べます。
マネジメントコンソールから Elastic Beanstalkの環境名とアプリケーション名を控えます。
S3バケットのzipファイル名も控えます。
"Deploy to Elastic Beanstalk"タスクにそれらを入力してください。
最後にトリガーの設定を行います。
Triggersタブから "Enable continuous integration"にチェックを入れてください。
対象ブランチを選択し、保存します。
自動デプロイの動作確認
ではVisual Studioを開き、 Views -> Home -> Index.cshtml の文言を変更してみましょう。
このファイルは先程Webアプリケーションをブラウザで確認したページのViewテンプレートです。
"Welcome" を "Welcome Hoge!!!"に変更しました。
変更後、リモートブランチへプッシュしてください。
プッシュ後にパイプラインを確認してください。
タスクが自動で開始されていると思います。
タスクが完了しましたね!
Elastic BeanstalkのURLへアクセスしてみましょう。
更新されていました!
さいごに
Azure DevOpsを使うとGUIでポチポチしながらテキストボックスを埋めていくだけでCI/CDパイプラインが構築出来ます。
Azureからはある程度切り離されており、様々な拡張機能をインストールすることでカスタマイズが可能です。
また、Azure DevOpsも組織の概念があり、ユーザーはAzureADでの管理が可能です。
無料利用(条件あり)も可能ですが、Visual Studioのライセンスを利用することも可能です。
CI/CD環境はAzure DevOps、インフラは AWS/GCPなども選択肢のひとつとしておもしろいとおもいます。